home *** CD-ROM | disk | FTP | other *** search
- // TRACK.CPP - Race Course definition
- // by Mitchell E. Timin, State College, PA
- // see CAR.H & TRACK.H for class and structure declarations
- // This version is for Borland C++, version 3.1, and is for DOS
- // This is part of version 0.60 of RARS (Robot Auto Racing Simulation)
- // ver. 0.1 release January 12, 1995
- // ver. 0.2 1/23/95
- // ver. 0.3 2/7/95
- // ver. 0.39 3/6/95
- // March 9 - build_track() changed to automatically handle degrees or radians
- // ver. 0.46 3/25/95
- // ver. 0.6b 5/8/95 b for beta
-
- /* (12.5.95) Added support for tracks that describe the centerline of the track instead of the
- * outer rail. This is triggered by specifying a negative number of segments.
- * (21.5.95) Made minor modifications which should work better on other platforms. Some of the
- * 8.3 filename handling code has been removed.
- * Marcel Offermans
- */
-
- #include <fstream.h>
- #include <stdlib.h>
- #include <string.h>
- #include "track.h"
- #include "gi.h" // needed only for resume_text_display()
-
- // array for track data file name:
- char trackfile[60];
-
- int NSEG; // number of track segments (see drawpath() in GRAPHICS.CPP)
- double X_MAX, Y_MAX; // maximum values that display must show, feet
- double width; // width of track, feet
- double TRK_STRT_X; // coordinates of where to start drawing track
- double TRK_STRT_Y; // (feet)
- double SCORE_BOARD_X; // These are in feet, track coordinates
- double SCORE_BOARD_Y; // (where the scoreboard is located)
- double LDR_BRD_X; // upper left corner of leader board, feet
- double LDR_BRD_Y;
- double LOTIX, LOTIY; // coords of start of "Length of track is ......"
- double IP_X, IP_Y; // Instrument Panel coordinates
- double FINISH; // fraction of segment 0 prior to finish line
- double from_start_to_seg1; // distance from start/finish line to end of segment
-
- // These two arrays describe the outer and inner boundaries of the track:
- segment *trackout;
- segment *trackin; // Note that the only difference between trackin and
- // trackout is a "width" feet smaller radius on the curves.
-
- void err_exit(void)
- {
- resume_normal_display();
- cout << "There is no track data file. :(" << endl;
- if(trackfile[0])
- cout << "Tried to find: " << trackfile << endl;
- exit(1);
- }
-
- // Reads the track definition file and builds the trackin and trackout
- // arrays. If the arc length of the first curve is < 5.0 the units are
- // assumed to be radians. Otherwise they are assumed to be degrees.
- void build_track()
- {
- ifstream inf(trackfile); // open the track file for input
- static int degrees = -1; // will become 1 for degrees, 0 for radians
- int i;
-
- /* flag indicating if this track is described by its centerline */
- static int centerline = 0;
- /* used in centerline parsing */
- double radius, length, halfwidth;
-
- /* if the trackfile couldn't be found, try appending .trk to the filename */
- if(!inf)
- {
- strcat(trackfile, ".trk");
- inf.open(trackfile);
- /* if that doesn't work either, we fail */
- if(!inf)
- {
- err_exit();
- }
- }
- else
- {
- /* check if the file had the .trk extension */
- if(strcmpnocase(&trackfile[(strlen(trackfile) - 4)], ".trk"))
- {
- resume_normal_display();
- cout << "Track data file should have a .trk extension." << endl;
- exit(1);
- }
- }
- inf >> NSEG;
-
- /* check for new type */
- if (NSEG < 0)
- {
- /* this is a new type of track, described by the centerline of the circuit */
- centerline = 1;
-
- /* make NSEG positive again */
- NSEG = -NSEG;
- }
-
- inf.ignore(120, '\n'); // ignore rest of line, up to 120 chars
- inf >> X_MAX >> Y_MAX;
- inf.ignore(120, '\n');
- inf >> width; // read the header section:
- inf.ignore(120, '\n');
- inf >> TRK_STRT_X >> TRK_STRT_Y;
- inf.ignore(120, '\n');
- inf >> SCORE_BOARD_X >> SCORE_BOARD_Y;
- inf.ignore(120, '\n');
- inf >> LDR_BRD_X >> LDR_BRD_Y;
- inf.ignore(120, '\n');
- inf >> IP_X >> IP_Y;
- inf.ignore(120, '\n');
- inf >> LOTIX >> LOTIY;
- inf.ignore(120, '\n');
- inf >> FINISH;
- inf.ignore(120, '\n');
-
- trackout = new segment[NSEG]; // allocate RAM for track segment arrays
- trackin = new segment[NSEG];
-
- /* centerline description? */
- if (centerline == 1)
- {
- halfwidth = width / 2.0;
- for (i = 0; i < NSEG; i++)
- {
- /* read the radius and length and ignore following comments */
- inf >> radius >> length;
- inf.ignore(120, '\n');
-
- /* check for degrees or radians */
- if ((degrees == -1) && (radius != 0))
- {
- /* it isn't pretty, but it works */
- if (length < 5.0)
- {
- degrees = 0;
- }
- else
- {
- degrees = 1;
- }
- }
-
- /* convert degrees to radians, if necessary */
- if ((degrees == 1) && (radius != 0.0))
- {
- length /= DEGPRAD;
- }
-
- /* fill in radius */
- if (radius == 0.0)
- {
- trackin[i].radius = 0.0;
- trackout[i].radius = 0.0;
- }
- else
- {
- trackin[i].radius = radius - halfwidth;
- trackout[i].radius = radius + halfwidth;
- }
-
- /* fill in length */
- trackin[i].length = length;
- trackout[i].length = length;
- }
- }
- else
- {
- /* this is the original track file reader routine */
-
- for(i=0; i<NSEG; i++) { // read the segment data:
- inf >> trackout[i].radius >> trackout[i].length;
- inf.ignore(120, '\n');
- // this section of the loop handles (degree vs. radians):
- if(degrees == -1 && trackout[i].radius != 0.0)
- if(trackout[i].length < 5.0)
- degrees = 0;
- else
- degrees = 1;
- if(degrees == 1 && trackout[i].radius != 0.0)
- trackout[i].length /= DEGPRAD;
- }
-
- for(i=0; i<NSEG; i++) { // fill in trackin[] from trackout[]
- if(trackout[i].radius == 0.0)
- trackin[i].radius = trackout[i].radius;
- else
- trackin[i].radius = trackout[i].radius - width;
- trackin[i].length = trackout[i].length;
- }
-
- /* end of the original track file reader routine */
- }
-
- // initialize this global variable:
- from_start_to_seg1 = (1.0 - FINISH) * trackout[0].length;
- }
-
- track_desc get_track_description(void)
- {
- track_desc ts;
-
- ts.NSEG = NSEG;
- ts.width = width;
- ts.trackout = trackout;
- ts.trackin = trackin;
- return ts;
- }
-